import json
import time
from concurrent.futures.thread import ThreadPoolExecutor
import uuid
from rest_framework.views import APIView
from wechatpy.utils import check_signature
from wechatpy import parse_message, create_reply
from wechatpy.exceptions import InvalidSignatureException, InvalidAppIdException

from wechatpy.crypto import WeChatCrypto
from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import AllowAny
from django.http import HttpResponse
from rest_framework.request import Request
import requests
import threading
from common.util.common import bytes_to_uploaded_file
from dataset.serializers.file_serializers import FileSerializer
from application.serializers.chat_serializers import ChatSerializers
from django.db.models import Q, QuerySet
from application.models import Application
from application.serializers.chat_message_serializers import ChatInfo, ChatMessageSerializer
from django.core.cache import caches
from dataset.serializers.file_serializers import FileSerializer

cache = caches['default_file']
chat_cache = caches['chat_cache']

from xpack.serializers.platform_serializer import ConfigSerializer

thread_pool = ThreadPoolExecutor(max_workers=20)

class FeishuMessage(APIView):
    def __init__(self, **kwargs):
        self.chat_id = None
        self.application_id = None
    def chat(self,messages,req):
        # {question} 为用户问题 {trigger_message} 继续
        # chat_record_id_cache_key = req['chat_id'] + '_chat_record_id'
        data = {
            'chat_id': req['chat_id'], 
            'message': messages['message'],
            're_chat': False,
            'stream': False,
            'application_id': req['application_id'],
            'client_id': req['client_id'],
            'form_data': {},
            'image_list': messages['image_list'],
            'document_list': [],
            'audio_list': [],
            'client_type': 'USER',
            'node_id': None,
            'runtime_node_id': None,
            'node_data': {},
            'chat_record_id': None,
            'child_node': {}
        }
        # chat_record_id = None
        chat_record_list = []
        response = ChatMessageSerializer(data = data).chat()
        res_list = []
        if response is None:
            chat_record_list = [{"content": "抱歉，没有查找到相关内容，请重新描述您的问题或提供更多信息。"}]
            chat_cache.set(messages['id'], chat_record_list)
            return messages['id']
        if response.status_code == 200:
            if response.content is not None:
                chat_record = json.loads(response.content)
                if chat_record['code'] == 200:
                    chat_record_list.append(chat_record['data'])
                    # chat_record_id = chat_record_list[0]['id']
                    # cache.set(chat_record_id_cache_key,chat_record_id)
            elif response.streaming_content is not None:
                res_list = list(response.streaming_content)
                if len(res_list) > 0:
                    for chunk in res_list:
                        if chunk[0:5] == b'data:':
                            jsons = json.loads(chunk[5:].decode('utf-8'))
                            if type(jsons['content']) != str:
                                continue
                            chat_record_list.append(jsons)
                    # chat_record_id = chat_record_list[0]['chat_record_id']
                    # cache.set(chat_record_id_cache_key,chat_record_id)
        # if chat_record_id is not None:
        chat_cache.set(messages['id'], chat_record_list)
        print('生成结果', chat_record_list)
        return messages['id']
    def get_access_token(self, appid, appsecret):
        access_token_cache_key = appid + '_access_token'
        access_token = cache.get(access_token_cache_key)
        if access_token is None:
            url = f"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
            headers = {
                'content-type': 'application/json; charset=UTF-8'
            }
            datas = {
                "app_id": appid,
                "app_secret": appsecret
            }
            response = requests.post(url, json=datas, headers=headers)
            data = response.json()
            if data.get('errcode', None) is not None:
                print('get_access_token', data.get('errmsg'))
                return None
            access_token = data.get('tenant_access_token', None)
            if access_token is not None:
                cache.set(access_token_cache_key, access_token, 7200)
        
        return access_token
    def get_media_info(self, msg, wx_config):
        access_token = self.get_access_token(wx_config['app_id'], wx_config['app_secret'])
        if access_token is None:
            return None
        mediaid = msg.media_id
        file_name = mediaid + '.' + msg.format
        url = f"https://api.weixin.qq.com/cgi-bin/media/get?access_token={access_token}&media_id={mediaid}"
        response = requests.get(url)
        # 确保请求成功
        if response.status_code == 200:
            # with open(file_name, 'wb') as f:
            #     for chunk in response.iter_content(chunk_size=8192):  # 8192字节的块
            #         f.write(chunk)
            file_bytes = response.content
            file = bytes_to_uploaded_file(file_bytes, file_name)
            return file
        else:
            print('Failed to retrieve the file')
            return None
    def send_custom_message(self, message_id, content, wx_config):
        access_token = self.get_access_token(wx_config['app_id'], wx_config['app_secret'])
        if access_token is None:
            return None
        url = f"https://open.feishu.cn/open-apis/im/v1/messages/{message_id}/reply"
        print(url)
        headers = {
            'content-type': 'application/json; charset=UTF-8',
            'Authorization': 'Bearer ' + access_token
        }
        contents = {
            'text': content
        }
        datas = {
            "msg_type": "text",
            "content": json.dumps(contents)
        }
        response = requests.post(url, json=datas, headers=headers)
        return response.json()
    @action(methods=['GET'], detail=False)
    @permission_classes((AllowAny,))
    def get(self, request: Request, application_id: str):
        #{'encrypt': 'uLGkPoe2Dnor1Y+QfPIkKHy6dU8LMTcSGRHXlTBjJNgXnyWvyOpZ+UTHikEnI55EQ2GWOhxRc/3Y62IcnHq63PhgOVezTj1so+9KV34YkJtFs7ilVRzohoWp5TwYJ+f0bMLJ040ui8M/tIB9cPYi/Su6ocS6Lxb5etr13tof2Vdj1Xa6dmrDIE7/7ZchVZuz'}
        where = {
            "app_id": application_id,
            "platform": "feishu",
        }
       
        return HttpResponse(json.dumps(where))
    def post(self, request: Request, application_id: str):
        jsonData = request.data
        if 'type' in jsonData and jsonData['type'] == 'url_verification':
            returnData['challenge'] = request.data.get('challenge')
            return HttpResponse(json.dumps(returnData))
        application = QuerySet(Application).filter(id=application_id).first()
        if application is None:
            return HttpResponse("应用不存在")
        user_id = str(application.user_id)
        where = {
            "app_id": application_id,
            "platform": "feishu",
        }
        wx_config = ConfigSerializer.Query(data = where).info()
        if wx_config is None:
            return HttpResponse("飞书配置不存在")
        
        req = {
            "signature": request.GET.get('signature', ''),
            "timestamp": request.GET.get('timestamp', ''),
            "nonce": request.GET.get('nonce', ''),
            "message_id": "",
            "encrypt_type": request.GET.get("encrypt_type", "raw"),
            "msg_signature": request.GET.get("msg_signature", ""),
            "application_id": application_id,
            "wechat_access_token": "",
            "chat_id": "",
            "openid": "",
            "user_id": user_id,
        }
        # file = open("get.txt", "w")
        # file.write(json.dumps(request.GET))
        # file.close()
        # file = open("body.txt", "w")
        # file.write(request.body.decode("utf-8"))
        # file.close()
        #消息内容 {'schema': '2.0', 'header': {'event_id': 'e8042e019ff477c9b95144d88919fa90', 'token': 'ABF69v6hT8fBC98SHaDPPgZpm4VBdv5w', 'create_time': '1742197539863', 'event_type': 'im.message.receive_v1', 'tenant_key': '14af25c38e94574f', 'app_id': 'cli_a74011541e36d01c'}, 'event': {'message': {'chat_id': 'oc_f8d786e9093ab463234eb924bc929da4', 'chat_type': 'p2p', 'content': '{"text":"你好"}', 'create_time': '1742197539466', 'message_id': 'om_59df03b0fefaf9ac0a170e6f1108e7bc', 'message_type': 'text', 'update_time': '1742197539466'}, 'sender': {'sender_id': {'open_id': 'ou_6d5be3a1e7e5ee07b7771ca5d80051d8', 'union_id': 'on_ac22f8edbd790ca13be11a34aeff8e63', 'user_id': None}, 'sender_type': 'user', 'tenant_key': '14af25c38e94574f'}}}
        if 'event' in jsonData:
            msg = jsonData['event']['message']
            sender = jsonData['event']['sender']
            req['openid'] = sender['sender_id']['open_id']
            req['message_id'] = msg['message_id']
            chat_id_cache_key = application_id + '_chatid_' + req['openid']
            client_id_cache_key = application_id + '_client_' + req['openid']
            client_id = cache.get(client_id_cache_key)
            if client_id is None:
                client_id = str(uuid.uuid1())
                cache.set(client_id_cache_key, client_id)
            chat_id = cache.get(chat_id_cache_key)
            if chat_id is None:
                chat_id = ChatSerializers.OpenChat(data={'user_id':user_id, 'application_id': application_id}).open()
                cache.set(chat_id_cache_key, chat_id)
            req['chat_id'] = chat_id
            req['client_id'] = client_id
            messages = {
                'id': str(uuid.uuid1()),
                'type': "text",
                'message': "随便回复点什么",
                'image_list': [],
                'audio_list': [],
            }
            if msg['message_type'] == 'text':
                messages['message'] = json.loads(msg['content']).get('text')
                messages['type'] = 'text'
            threading.Thread(target=self.chat, args=(messages, req)).start()
            threading.Thread(target=self.async_reply, args=(messages,req, wx_config)).start()
        self.handle_reply(msg, req, wx_config)
        return HttpResponse("success")
    def handle_reply(self,msg,req,wx_config):
        rcontent = "请稍候，正在处理中。。。"
        self.send_custom_message(req['message_id'], rcontent, wx_config)
        return rcontent
    def async_reply(self, messages, req, wx_config):
        i = 0
        while True:
            time.sleep(3)
            print("聊天记录ID", messages['id'])
            chat_record_list = chat_cache.get(messages['id'])
            print("本次消息", chat_record_list)
            
            if i >= 10:
                print("抱歉，没有查找到相关内容，请重新描述您的问题或提供更多信息。")
                return False
            i+=1
            if chat_record_list is not None and len(chat_record_list) > 0:
                content = ""
                for chat_record in chat_record_list:
                    content += chat_record['content']
                n = 600
                segments = [content[i:i + n] for i in range(0, len(content), n)]
                for segment in segments:
                    print(segment)
                    self.send_custom_message(req['message_id'], segment, wx_config)
                
                return True
  